using System;
using System.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Net;
using System.ComponentModel;
using System.Net.Http;

namespace Toolbox
{
    internal static class Program
    {
        // 使用互斥体检测程序实例
        private const string MutexName = "ToolboxAppMutex";
        private static Mutex? _mutex = null;
        
        // Windows API函数，用于查找窗口、发送消息
        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        
        [DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
        
        private const int WM_CLOSE = 0x0010;
        
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            // 添加全局异常处理
            Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

            // 检测.NET 8.0运行时
            if (!CheckDotNetRuntime())
            {
                // 如果未安装.NET 8.0运行时，询问用户是否下载安装
                if (MessageBox.Show(
                    "未检测到.NET 8.0运行时环境。\n\n是否自动下载并安装.NET 8.0运行时？",
                    "需要.NET 8.0运行时",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Information) == DialogResult.Yes)
                {
                    try
                    {
                        InstallDotNetRuntime();
                        // 安装完成后重新检测
                        if (!CheckDotNetRuntime())
                        {
                            MessageBox.Show(
                                ".NET 8.0运行时安装失败，请手动安装。\n\n下载地址：https://dotnet.microsoft.com/download/dotnet/8.0",
                                "安装失败",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                            return;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(
                            $"安装过程中发生错误：{ex.Message}\n\n请手动下载并安装.NET 8.0运行时。",
                            "安装错误",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
                        return;
                    }
                }
                else
                {
                    // 用户选择不安装，显示提示信息
                    MessageBox.Show(
                        "程序需要.NET 8.0运行时才能运行。\n\n请从以下地址下载并安装：https://dotnet.microsoft.com/download/dotnet/8.0",
                        "需要.NET 8.0运行时",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                    return;
                }
            }
            
            // 尝试创建互斥体，检测是否已有实例在运行
            bool createdNew;
            _mutex = new Mutex(true, MutexName, out createdNew);
            
            // 如果互斥体已存在，说明已有实例在运行
            if (!createdNew)
            {
                // 找到已存在的实例窗口
                IntPtr existingWindowHandle = FindWindow("", "我的工具箱");
                if (existingWindowHandle != IntPtr.Zero)
                {
                    // 询问用户是否关闭已有实例，设置消息框置顶显示
                    DialogResult result = MessageBox.Show(
                        "程序已在运行中。是否关闭现有程序并启动新程序？\n\n选择'是'：关闭现有程序并启动新程序\n选择'否'：取消启动新程序", 
                        "程序已运行", 
                        MessageBoxButtons.YesNo, 
                        MessageBoxIcon.Question, 
                        MessageBoxDefaultButton.Button1, 
                        MessageBoxOptions.DefaultDesktopOnly);
                    
                    if (result == DialogResult.Yes)
                    {
                        // 发送关闭消息给已有实例
                        SendMessage(existingWindowHandle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
                        // 等待一段时间让旧程序关闭
                        Thread.Sleep(1000);
                        // 继续启动新程序
                        RunApplication();
                    }
                    // 如果用户选择否，则不启动新程序
                    return;
                }
            }
            
            // 正常启动程序
            RunApplication();
        }
        
        /// <summary>
        /// 运行应用程序
        /// </summary>
        private static void RunApplication()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
            
            // 释放互斥体
            if (_mutex != null)
            {
                _mutex.ReleaseMutex();
                _mutex.Dispose();
            }
        }
        
        /// <summary>
        /// 检查是否安装了.NET 8.0运行时
        /// </summary>
        private static bool CheckDotNetRuntime()
        {
            try
            {
                // 1. 首先尝试通过命令行检查dotnet运行时版本
                try
                {
                    Process process = new Process
                    {
                        StartInfo = new ProcessStartInfo
                        {
                            FileName = "dotnet",
                            Arguments = "--list-runtimes",
                            RedirectStandardOutput = true,
                            RedirectStandardError = true,
                            UseShellExecute = false,
                            CreateNoWindow = true
                        }
                    };
                    
                    process.Start();
                    string output = process.StandardOutput.ReadToEnd();
                    string error = process.StandardError.ReadToEnd();
                    process.WaitForExit();
                    
                    // 日志：显示dotnet命令的输出（仅用于调试）
                    // Console.WriteLine("dotnet --list-runtimes output: " + output);
                    
                    // 更灵活地检查输出中是否包含.NET 8.0 Windows桌面运行时（支持任何8.x版本）
                    // 检查所有可能的变体，包括不同的空格和版本号格式
                    bool hasDotNet8Runtime = 
                        output.IndexOf("Microsoft.WindowsDesktop.App 8.", StringComparison.OrdinalIgnoreCase) >= 0 ||
                        output.IndexOf("Microsoft.WindowsDesktop.App,Version=8.", StringComparison.OrdinalIgnoreCase) >= 0 ||
                        output.IndexOf("Microsoft.WindowsDesktop.App\t8.", StringComparison.OrdinalIgnoreCase) >= 0;
                    
                    if (hasDotNet8Runtime)
                    {
                        return true;
                    }
                    
                    // 也添加对6.0的支持作为后备
                    bool hasDotNet6Runtime = 
                        output.IndexOf("Microsoft.WindowsDesktop.App 6.", StringComparison.OrdinalIgnoreCase) >= 0 ||
                        output.IndexOf("Microsoft.WindowsDesktop.App,Version=6.", StringComparison.OrdinalIgnoreCase) >= 0 ||
                        output.IndexOf("Microsoft.WindowsDesktop.App\t6.", StringComparison.OrdinalIgnoreCase) >= 0;
                    
                    if (hasDotNet6Runtime)
                    {
                        return true;
                    }
                }
                catch (Exception)
                {
                    // 命令执行失败，继续尝试其他检测方法
                }
                
                // 2. 尝试通过注册表检查
                if (CheckDotNetRuntimeViaRegistry())
                {
                    return true;
                }
                
                // 3. 尝试通过目录检查
                if (CheckDotNetRuntimeViaDirectory())
                {
                    return true;
                }
                
                // 4. 特别检查Windows Desktop Runtime 8.0.20可能的安装路径
                string[] specificPaths = new string[]
                {
                    Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "dotnet", "shared", "Microsoft.WindowsDesktop.App", "8.0.20"),
                    Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "dotnet", "shared", "Microsoft.WindowsDesktop.App", "8.0.20")
                };
                
                foreach (string path in specificPaths)
                {
                    if (Directory.Exists(path))
                    {
                        // Console.WriteLine("找到特定版本路径: " + path);
                        return true;
                    }
                }
                
                return false;
            }
            catch (Exception)
            {
                return false;
            }
        }
        
        /// <summary>
        /// 通过注册表检查.NET 8.0运行时是否安装
        /// </summary>
        private static bool CheckDotNetRuntimeViaRegistry()
        {
            try
            {
                // 检查32位和64位注册表路径
                string[] registryPaths = new string[]
                {
                    @"SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedfx\Microsoft.WindowsDesktop.App",
                    @"SOFTWARE\WOW6432Node\dotnet\Setup\InstalledVersions\x64\sharedfx\Microsoft.WindowsDesktop.App",
                    @"SOFTWARE\dotnet\Setup\InstalledVersions\x86\sharedfx\Microsoft.WindowsDesktop.App",
                    @"SOFTWARE\WOW6432Node\dotnet\Setup\InstalledVersions\x86\sharedfx\Microsoft.WindowsDesktop.App"
                };
                
                foreach (string path in registryPaths)
                {
                    using (Microsoft.Win32.RegistryKey? key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path))
                    {
                        if (key != null)
                        {
                            string? version = key.GetValue("Version") as string;
                            version ??= string.Empty;
                            if (!string.IsNullOrEmpty(version) &&
                                (version.StartsWith("8.") || version.StartsWith("6.")))
                            {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
            catch
            {
                return false;
            }
        }
        
        /// <summary>
        /// 通过检查文件目录是否存在来确认.NET 8.0运行时是否安装
        /// </summary>
        private static bool CheckDotNetRuntimeViaDirectory()
        {
            try
            {
                // 检查Program Files和Program Files (x86)目录
                string[] programFilesPaths = new string[]
                {
                    Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
                    Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)
                };
                
                foreach (string programFilesPath in programFilesPaths)
                {
                    // 检查所有可能的8.x版本目录
                    string dotNetPath = Path.Combine(programFilesPath, "dotnet", "shared", "Microsoft.WindowsDesktop.App");
                    if (Directory.Exists(dotNetPath))
                    {
                        // 检查是否有8.x或6.x版本的子目录
                        foreach (string versionDir in Directory.GetDirectories(dotNetPath))
                        {
                            string versionName = Path.GetFileName(versionDir);
                            if (versionName.StartsWith("8.") || versionName.StartsWith("6."))
                            {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
            catch
            {
                return false;
            }
        }
        
        /// <summary>
        /// 自动下载并安装.NET 8.0运行时
        /// </summary>
        private static void InstallDotNetRuntime()
        {
            // 显示安装进度对话框
            using (var progressForm = new Form
            {
                Text = "安装.NET 8.0运行时",
                Width = 400,
                Height = 150,
                FormBorderStyle = FormBorderStyle.FixedDialog,
                StartPosition = FormStartPosition.CenterScreen,
                MaximizeBox = false,
                MinimizeBox = false
            })
            {
                var label = new Label
                {
                    Text = "正在下载.NET 8.0运行时安装程序...",
                    Dock = DockStyle.Top,
                    Padding = new Padding(10),
                    TextAlign = System.Drawing.ContentAlignment.MiddleCenter
                };
                
                var progressBar = new ProgressBar
                {
                    Dock = DockStyle.Bottom,
                    Minimum = 0,
                    Maximum = 100,
                    Value = 0
                };
                
                progressForm.Controls.Add(label);
                progressForm.Controls.Add(progressBar);
                
                // 在单独线程中下载并安装
                var backgroundWorker = new BackgroundWorker
                {
                    WorkerReportsProgress = true
                };
                
                backgroundWorker.DoWork += (sender, e) =>
                {
                    try
                    {
                        string tempInstallerPath = Path.Combine(Path.GetTempPath(), "dotnet-runtime-installer.exe");
                        
                        // 下载安装程序 - 使用HttpClient替代过时的WebClient
                        using (var client = new HttpClient())
                        {
                            client.Timeout = TimeSpan.FromMinutes(10); // 设置超时时间
                            
                            // 使用直接下载链接
                            var downloadTask = client.GetByteArrayAsync(
                                "https://download.visualstudio.microsoft.com/download/pr/a486e781-1b4c-40d0-9061-f7d7e2d3832b/0ea89f3a9ff531e62f6d7d712f06f868/windowsdesktop-runtime-8.0.5-win-x64.exe");
                            
                            // 模拟进度报告（HttpClient不直接支持进度报告）
                            for (int i = 0; i < 90; i += 5)
                            {
                                if (downloadTask.IsCompleted)
                                    break;
                                backgroundWorker.ReportProgress(i, "正在下载.NET 8.0运行时安装程序...");
                                Thread.Sleep(500);
                            }
                            
                            byte[] data = downloadTask.GetAwaiter().GetResult();
                            File.WriteAllBytes(tempInstallerPath, data);
                        }
                        
                        backgroundWorker.ReportProgress(100, "正在安装.NET 8.0运行时...");
                        
                        // 运行安装程序
                        Process? installerProcess = Process.Start(new ProcessStartInfo
                        {
                            FileName = tempInstallerPath,
                            Arguments = "/quiet /norestart",
                            UseShellExecute = true
                        });
                        if (installerProcess != null)
                        {
                            installerProcess.WaitForExit();
                        }
                        
                        // 清理临时文件
                        if (File.Exists(tempInstallerPath))
                        {
                            File.Delete(tempInstallerPath);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception($"下载或安装过程失败: {ex.Message}");
                    }
                };
                
                backgroundWorker.ProgressChanged += (sender, e) =>
                {
                    progressBar.Value = e.ProgressPercentage;
                    label.Text = e.UserState?.ToString() ?? string.Empty;
                };
                
                backgroundWorker.RunWorkerCompleted += (sender, e) =>
                {
                    if (e.Error != null)
                    {
                        throw e.Error;
                    }
                    progressForm.Close();
                };
                
                backgroundWorker.RunWorkerAsync();
                progressForm.ShowDialog();
            }
        }

        #region 异常处理
        /// <summary>
        /// 处理UI线程异常
        /// </summary>
        private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            LogException(e.Exception, "UI线程异常");
        }

        /// <summary>
        /// 处理非UI线程未捕获异常
        /// </summary>
        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception? ex = e.ExceptionObject as Exception;
            if (ex != null)
            {
                LogException(ex, "未处理的应用程序异常", e.IsTerminating);
            }
        }

        /// <summary>
        /// 记录异常信息到日志文件
        /// </summary>
        private static void LogException(Exception ex, string title, bool isTerminating = false)
        {
            try
            {
                // 创建日志文件路径
                string logPath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath) ?? Environment.CurrentDirectory, "error_log.txt");
                
                // 构建异常信息
                StringBuilder logMessage = new StringBuilder();
                logMessage.AppendLine("==================================================");
                logMessage.AppendLine($"时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
                logMessage.AppendLine($"类型: {title}");
                logMessage.AppendLine($"终止应用: {isTerminating}");
                logMessage.AppendLine($"消息: {ex.Message}");
                logMessage.AppendLine($"堆栈: {ex.StackTrace}");
                if (ex.InnerException != null)
                {
                    logMessage.AppendLine("内部异常:");
                    logMessage.AppendLine($"消息: {ex.InnerException.Message}");
                    logMessage.AppendLine($"堆栈: {ex.InnerException.StackTrace}");
                }
                logMessage.AppendLine("==================================================");
                logMessage.AppendLine();
                
                // 写入日志文件
                File.AppendAllText(logPath, logMessage.ToString(), Encoding.UTF8);
                
                // 在控制台显示错误，方便调试
                Console.WriteLine("\n" + logMessage.ToString());
                
                // 显示错误消息框
                if (!isTerminating)
                {
                    MessageBox.Show(
                        $"应用程序发生错误:\n{ex.Message}\n\n详细信息已记录到日志文件。",
                        "应用程序错误",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }
            }
            catch { }
        }
        #endregion

    }
}